import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class mockito {

    @Spy
    List<String> list = new ArrayList<String>();

    @Mock
    private List mockedList;

    @Before
    public void createList() {
        //创建mock对象
        this.mockedList = Mockito.mock(List.class);
    }


    @Test
    public void when_thenReturn() {
        //测试桩
        when(mockedList.get(eq(0))).thenReturn("oo");

        //断言
        assertThat(mockedList.get(0)).isEqualTo("oo");
    }

    @Test
    public void mock(){
        when(mockedList.get(anyInt())).thenReturn(1,2,3);
        assertThat(mockedList.get(1)).isEqualTo(1);
        assertThat(mockedList.get(1)).isEqualTo(2);
        assertThat(mockedList.get(1)).isEqualTo(3);
    }

    @Test
    public void stubbing_answer(){
        when(mockedList.get(anyInt())).thenAnswer(new Answer<Object>() {
            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
                Integer index = invocationOnMock.getArguments().length;
                return String.valueOf(index * 10);
            }
        });
        assertThat(mockedList.get(0)).isEqualTo("10");
    }

    @Test
    public void testSpy(){
        /*List<String> reallist = new ArrayList<String>();
        List<String> list = spy(reallist);*/

        list.add("hh");

        assertThat(list.get(0)).isEqualTo("hh");
    }

    @Test
    public void testThenCallRealMethod(){
        CallRealMeathod realMeathod = Mockito.mock(CallRealMeathod.class);

        assertThat(realMeathod.getMessage()).isEqualTo(null);

        when(realMeathod.getMessage()).thenCallRealMethod();

        assertThat(realMeathod.getMessage()).isEqualTo("thenCallRealMethod");
    }

    @Test
    public void matchers() {
        //使用内置的anyInt()参数匹配器
        when(mockedList.get(anyInt())).thenReturn("argument matchers");

        //断言
        assertThat(mockedList.get(888)).isEqualTo("argument matchers");
    }

    @Test
    public void self_matchers(){

        assertThat(mockedList.addAll(Arrays.asList())).isFalse();

        //使用自定义的参数匹配器
        when(mockedList.add(argThat(new First()))).thenReturn(true);

        //断言
        assertThat(mockedList.add(Arrays.asList("one"))).isTrue();
        assertThat(mockedList.addAll(Arrays.asList("one", "two", "three"))).isFalse();
    }

}
